package com.gsi.webstore.platform.storefront.capi.product;

import java.util.Collection;
import java.util.List;

import com.intershop.beehive.core.capi.localization.LocaleInformation;
import com.intershop.beehive.foundation.quantity.Money;
import com.intershop.component.marketing.capi.rebate.Promotion;

public interface ProductBO extends com.intershop.component.product.capi.ProductBO
{
    /**
     * collect all category accessories and product accessories and concatenate
     * the results to an iterator
     * 
     * @return
     */    
    public List<com.intershop.component.product.capi.ProductBO> getAccessoriesWithFallback();
    
    /**
     * Check product availability status and return the message corresponding to
     * the state. Try first to get the message from the product, then from the
     * catalog and finally from the repository. Since availability message is
     * localizable, the locale from current request is assumed
     * 
     * @return availability message
     */
    public String getAvailabilityMessage();

    /**
     * Check product availability status and return the message corresponding to
     * the state. Try first to get the message from the product, then from the
     * catalog and finally from the repository. Since availability message is
     * localizable, the locale from current request is assumed
     * 
     * @return availability message
     */
    public String getAvailabilityDateMessage();

    /**
     * Check product availability status and return the message corresponding to
     * the state. Try first to get the message from the product, then from the
     * catalog and finally from the repository
     * 
     * @param locale
     *            the locale of availability message
     * @return availability message
     */
    public String getAvailabilityMessage(LocaleInformation locale);
    /**
     * Gets shipping window message.
     * 
     * @return ship window message
     */
    public String getShipWindowMessage();
    /**
     * Gets shipping window lower bound. The method is searching for lower bound
     * value at the product first, then at product catalog and product
     * repository
     * 
     * @return ship window lower bound
     */
    public String getShippingWindowLowerBound();
    /**
     * Gets shipping window higher bound. The method is searching for higher
     * bound value at the product first, then at product catalog and product
     * repository
     * 
     * @return ship window higher bound
     */
    public String getShippingWindowHigherBound();


    /**
     * This method returns true if (and only if) a LegalPurchaseAge is set at this product. 
     * In this case the product is age restricted.
     * 
     * @return true if (and only if) a LegalPurchaseAge is set at this product, otherwise false.
     */
    boolean isAgeRestricted();
    
    
    /**
     * Returns the consumer's minimum age in years required to purchase 
     * this product. If a LegalPurchaseAge is set, then the product is age 
     * restricted and must not be sold to consumers under that age. 
     * Do not confuse this with the recommended age. This method returns null 
     * if no LegalPurchaseAge is set. In this case the product is not 
     * age restricted.
     * 
     * @return the consumer's minimum age in years required to purchase 
     * this product or null, if no LegalPurchaseAge is set
     */
    public Integer getLegalPurchaseAge(); 
    
    /**
     * Returns the age rating classification or description 
     * (a localized attribute) for the current locale.
     * 
     * @return the age rating classification or description 
     * (a localized attribute) for the current locale
     */
    public String getAgeRating(); 
    
    /**
     * Returns the age rating classification or description for the 
     * specified locale.
     * 
     * @param aLocale the provided LocaleInformation
     * @return the age rating classification or description for the 
     * specified locale
     */
    public String getAgeRating(LocaleInformation aLocale); 
    
    /**
     * Returns the product was price.
     * 
     * @return the product was price
     */
    public Money getWasPrice();
    
    /**
     * Returns the product min was price.
     * 
     */
    public Money getMinimumWasPrice();
    
    /**
     * Returns the product max was price.
     * 
     */
    public Money getMaximumWasPrice();
   
    /**
     * 
     * Returns the product ShopRunner eligibility.
     */
    public boolean isShopRunnerEligible();
    
    /**
     * Returns a mail-in rebate promotion
     * 
     * @param applicablePromotions list of applicable promotions
     * @return the mail-in rebate promotion
     */
    public Promotion getMailInRebate(Collection<Promotion> applicablePromotions);
    
    /**
     * Calculates the discount amount  based on ProductBO:ProductPrice("SalePrice").
     * 
     * @param aPromotion a promotion
     * @return the discount amount
     */
    public Money getDiscountAmount(Promotion aPromotion);
    
    /**
     * Calculates the discounted price based on ProductBO:ProductPrice("SalePrice").
     * 
     * @param aPromotion a promotion
     * @return the discounted price
     */
    public Money getDiscountedPrice(Promotion aPromotion);
}
